package dca

import (
	"bytes"
	"encoding/binary"
	"math/rand"
)

// CycleShiftLeft 循环左移函数
// 将num循环左移n位
func CycleShiftLeft(num uint32, n int) uint32 {
	return (num << n) | (num >> (32 - n))
}

// CycleShiftRight 循环右移函数
// 将num循环右移n位
func CycleShiftRight(num uint32, n uint8) uint32 {
	return (num >> n) | (num << (32 - n))
}

// RandomKey 生成随机比特位的秘钥
func RandomKey(n int) []uint32 {
	if n%32 != 0 {
		return nil
	}
	res := make([]uint32, 0, n/32)
	for i := 0; i < n/32; i++ {
		res = append(res, rand.Uint32())
	}
	return res
}

// toByteSlice 将[]uint32转换为[]byte
func toByteSlice(num []uint32) []byte {
	res := make([]byte, 0, len(num)*4)
	for i := 0; i < len(num); i++ {
		res = append(res, uint32ToUint8(num[i])...)
	}
	return res
}

// uint32ToUint8 将uint32转换为uint8的数组
func uint32ToUint8(num uint32) []uint8 {
	res := make([]uint8, 4)
	binary.BigEndian.PutUint32(res, num)
	return res
}

func PKCS7Padding(cipherText []byte, blockSize int) []byte {
	padding := blockSize - len(cipherText)%blockSize
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(cipherText, padText...)
}

// Unpadding PKCS7填充方式的解填充方法
func Unpadding(src []byte) []byte {
	n := len(src)
	if n == 0 {
		return src
	}
	paddingNum := int(src[n-1])
	return src[:n-paddingNum]
}

// StringToUint32 将string转换为uint32数组，采用0字节填充
func StringToUint32(text string) []uint32 {
	slice := []byte(text)
	res := make([]uint32, 0, len(slice)/4)
	for i := 0; i < len(slice); i += 4 {
		res = append(res, binary.BigEndian.Uint32(slice[i:i+4]))
	}
	res = fillText(res)
	return res
}

// byteToUint32 将byte数组转化为uint32数组
func ByteToUint32(num []byte) []uint32 {
	res := make([]uint32, 0, len(num)/4)
	for i := 0; i < len(num); i += 4 {
		res = append(res, binary.BigEndian.Uint32(num[i:i+4]))
	}
	return res
}

// fillText 填充明文和密钥，使它们为128的倍数
func fillText(text []uint32) []uint32 {
	if len(text)%4 == 0 {
		return text
	}
	size := 4 - len(text)%4
	zeroUint32 := make([]uint32, size)
	text = append(text, zeroUint32...)
	return text
}
